package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.User;
import com.tbit.uqbike.object.pojo.VipCard;
import com.tbit.uqbike.object.pojo.VipCardLog;
import com.tbit.uqbike.object.pojo.dto.ClubRecordDTO;
import com.tbit.uqbike.object.pojo.dto.GiveClubCardDTO;
import com.tbit.uqbike.object.pojo.dto.ImportUserDTO;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.uqbike.object.pojo.vo.GiveRideCardVo;
import com.tbit.uqbike.object.pojo.vo.VipGiveLog;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.common.entity.view.PageResult;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.BatchGiveClubCardService;
import com.tbit.uqbike.webmanager.dao.core.BatchGiveClubCardDao;
import com.tbit.uqbike.webmanager.dao.log.VipGiveLogDao;
import com.tbit.uqbike.webmanager.util.DateUtils;
import com.tbit.uqbike.webmanager.util.StringUtils;
import com.tbit.uqbike.webmanager.util.adaPay.AdaPayUtil;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * @Author lhx
 * @ClassName BatchGiveClubCardServiceImpl
 * @Description
 * @date 2023/3/21 11:37
 * @Version 1.0
 */
@Slf4j
@Service
public class BatchGiveClubCardServiceImpl implements BatchGiveClubCardService {


    @Autowired
    private BatchGiveClubCardDao batchGiveClubCardDao;

    @Autowired
    private VipGiveLogDao vipGiveLogDao;


    @Override
    public Result<List<GiveRideCardVo>> giveClubCard(GiveClubCardDTO giveClubCardDTO, LoginInfo login, MultipartFile file) {
        Integer brandId = giveClubCardDTO.getAccountId();
        //接收到的手机号
        List<String> phoneList = new ArrayList<>();
        //存在会员卡且未到期的手机号
        List<String> haveClubCardList = new ArrayList<>();
        //赠送会员卡的手机号
        List<String> giveClubCardList = new ArrayList<>();
        //该手机号不存在
        List<String> phoneNotInDbList;
        //解析excel
        Workbook workbook;
        try {
            workbook = WorkbookFactory.create(Objects.requireNonNull(AdaPayUtil.MultipartFileToFile(file)));
            Sheet sheet = workbook.getSheetAt(0);
            Integer phoneIndex = null;
            boolean flag = true;
            for (Row row : sheet) {
                if (flag) {
                    //第一行为标题
                    Iterator<Cell> cellIterator = row.cellIterator();
                    while (cellIterator.hasNext()) {
                        Cell cell = cellIterator.next();
                        if ("手机号码".equals(cell.getStringCellValue())) {
                            phoneIndex = cell.getColumnIndex();
                        }
                    }
                    if (phoneIndex == null) {
                        return Result.error("excel文件数据有误");
                    }
                    flag = false;
                    continue;
                }
                //设置excel单元格类型
                row.getCell(phoneIndex).setCellType(CellType.STRING);
                String phone = row.getCell(phoneIndex).toString();
                if (StringUtils.isNotEmpty(phone)){
                    phoneList.add(phone);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("请检查文件excel是否有误");
        }
        //限制单次赠送5000
        int upperLimit = 2000;
        if (phoneList.size() > upperLimit) {
            return Result.error("单次赠送人数超过上限，每次仅允许赠送2000人");
        }
        //限制备注的长度
        if (giveClubCardDTO.getRemark().length() > 100) {
            return Result.error("备注过长，请重新输入");
        }
        //查询会员卡信息
        VipCard vipCard = batchGiveClubCardDao.getById(giveClubCardDTO.getVipId());
        if (vipCard == null) {
            throw new BaseException("会员卡不存在");
        }
        List<String> inDBList = batchGiveClubCardDao.getuserListbypa(phoneList, giveClubCardDTO.getAccountId());
        //剩下手机号不存在数据库
        phoneList.removeAll(inDBList);
        phoneNotInDbList = phoneList;

        Map<String, Map<String, Object>> userMap = new HashMap<>();
        if (!inDBList.isEmpty()) {
            userMap = batchGiveClubCardDao.getUserMap(inDBList, brandId);
        }
        List<VipCardLog> vipCardLogList = new LinkedList<>();
        List<VipGiveLog> vipGiveLogList = new LinkedList<>();
        //查询是否存在会员卡的用户
        List<Integer> userIdList = new ArrayList<>();
        Map<Integer, String> idPhoneMap = new HashMap<>();
        //循环处理
        for (String phone : inDBList) {
            Map<String, Object> map = userMap.get(phone);
            if (map == null) {
                continue;
            }
            Integer userId = (Integer) map.get("userId");
            userIdList.add(userId);
            idPhoneMap.put(userId, phone);
        }
        if (!userIdList.isEmpty()) {
            List<Integer> idList = batchGiveClubCardDao.getvipbypa(userIdList, vipCard.getAccountId());
            for (Integer id : idList) {
                haveClubCardList.add(idPhoneMap.get(id));
            }
        }
        inDBList.removeAll(haveClubCardList);
        for (String phone : inDBList) {
            Map<String, Object> map = userMap.get(phone);
            if (map == null) {
                continue;
            }
            //批量赠送会员卡
            Date nowTime = new Date();
            VipCardLog addVipCardLog = new VipCardLog();
            addVipCardLog.setVipId(giveClubCardDTO.getVipId());
            addVipCardLog.setAccountId(vipCard.getAccountId());
            addVipCardLog.setMemberState(1);
            addVipCardLog.setRemark(giveClubCardDTO.getRemark());
            addVipCardLog.setOrderNO(String.format("SystemGive%s", IdUtil.fastSimpleUUID()));
            addVipCardLog.setUserId((Integer) map.get("userId"));
            String date = DateTimeUtil.getNowTimeYMD();
            addVipCardLog.setExpireDate(DateTimeUtil.getServiceEndDate(date, vipCard.getType()));
            addVipCardLog.setEffectDate(date);
            addVipCardLog.setBuyTime(nowTime);
            addVipCardLog.setPayTime(nowTime);
            addVipCardLog.setIsGive(1);
            vipCardLogList.add(addVipCardLog);
            //同步记录表
            VipGiveLog vipgivelog = new VipGiveLog()
                    .setUserId((Integer) map.get("userId"))
                    .setPhone(map.get("phone").toString())
                    .setBrandId(giveClubCardDTO.getAccountId())
                    .setAccountId(vipCard.getAccountId())
                    .setVipId(vipCard.getVipId())
                    .setVipName(vipCard.getName())
                    .setGiveTime(DateUtils.getTime())
                    .setExpireDate(addVipCardLog.getExpireDate())
                    .setOrderNo(addVipCardLog.getOrderNO())
                    .setOperatorId(login.accountUserId)
                    .setOperatorPhone(login.phone)
                    .setRemark(giveClubCardDTO.getRemark());
            vipGiveLogList.add(vipgivelog);
            giveClubCardList.add(phone);
        }
        //批量插入数据
        if (!vipCardLogList.isEmpty() && !vipGiveLogList.isEmpty()) {
            batchGiveClubCardDao.insertByList(vipCardLogList);
            vipGiveLogDao.insertByList(vipGiveLogList);
        }

        List<GiveRideCardVo> failList = new ArrayList<>();
        GiveRideCardVo giveRideCardVo = null;
        for (String abnormalPhone : haveClubCardList) {
            giveRideCardVo = new GiveRideCardVo();
            giveRideCardVo.setPhone(abnormalPhone);
            giveRideCardVo.setFailMsg("已有生效中会员卡");
            failList.add(giveRideCardVo);
        }
        for (String failPhone : phoneNotInDbList) {
            giveRideCardVo = new GiveRideCardVo();
            giveRideCardVo.setPhone(failPhone);
            giveRideCardVo.setFailMsg("用户不存在");
            failList.add(giveRideCardVo);
        }
        return Result.success(failList);
    }


    @Override
    public PageResult<VipGiveLog> queryPageClubRecord(ClubRecordDTO clubRecordDTO) {
        //切割区域id存进list
        isNullAndTurnInteager(clubRecordDTO);
        PageInfo<VipGiveLog> pageInfo = PageHelper.startPage(clubRecordDTO.getPage(), clubRecordDTO.getSize()).doSelectPageInfo(() -> vipGiveLogDao.queryVipGiveLog(clubRecordDTO));
        return new PageResult<>(clubRecordDTO.getPage(), clubRecordDTO.getSize(), pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
    }

    @Override
    public Result<BatchOperationMsgVO<String>> importUser(ImportUserDTO importUserDTO) {
        List<String> phoneList = importUserDTO.getPhone();
        if (CollUtil.isEmpty(phoneList)) {
            return Result.error("请输入手机号");
        }
        //限定长度
        int phoneSize = 2000;
        if (phoneList.size() > phoneSize) {
            return Result.error("添加用户过多，请不要超过2000");
        }
        if (importUserDTO.getRemark().length() > 100) {
            return Result.error("备注过长，请重新输入");
        }
        //插入成功手机号列表
        List<String> successPhoneList = new ArrayList<>();
        //插入失败手机号列表
        List<String> failPhoneList = new ArrayList<>();

        String nowTime = DateUtils.getTime();
        //循环处理
        for (String phone : phoneList) {
            //检验手机号长度
            if ("".equals(phone) || phone == null) {
                return Result.error("请输入正确的手机号");
            }
            if (!phone.matches("^1[0-9]{10}$")) {
                return Result.error("请输入正确的手机号");
            }
            if (phone.length() != 11) {
                failPhoneList.add(phone);
            }
        }
        List<String> inDBList = batchGiveClubCardDao.selectPhone(importUserDTO.getAccountId(), phoneList);
        failPhoneList.addAll(inDBList);
        phoneList.removeAll(failPhoneList);
        List<User> userList = new ArrayList<>();
        for (String phone : phoneList) {
            User user = new User();
            user.setAccountId(importUserDTO.getAccountId());
            user.setPhone(phone);
            user.setRemark(importUserDTO.getRemark());
            user.setJoinTime(nowTime);
            userList.add(user);
        }
        if (!userList.isEmpty()) {
            batchGiveClubCardDao.importUserByList(userList);
            successPhoneList.addAll(phoneList);
        }
        //批量insert
        //构建返回对象
        BatchOperationMsgVO<String> batchOperationMsgVO = new BatchOperationMsgVO<>();
        batchOperationMsgVO.setSuccessList(successPhoneList)
                .setFailList(failPhoneList);
        return Result.success(batchOperationMsgVO);

    }

    @Override
    public Result exportClubCardRecord(ClubRecordDTO clubRecordDTO) {
        //切割区域id存进list
        isNullAndTurnInteager(clubRecordDTO);
        //导出前判断要导出数据是否大于限制
        int count = vipGiveLogDao.queryVipGiveLogCount(clubRecordDTO);
        if (count > 60000) {
            return Result.error("导出数据超过限制，请选择合适的条件");
        }
        clubRecordDTO.setPage(1);
        clubRecordDTO.setSize(60000);
        PageResult<VipGiveLog> pageResult = queryPageClubRecord(clubRecordDTO);
        List<VipGiveLog> list = pageResult.getList();
        ExcelUtil<VipGiveLog> excel = new ExcelUtil<>(VipGiveLog.class);
        JsonResult jsonResult = excel.exportExcel(list, "会员卡赠送记录");
        return Result.success(jsonResult.getData());
    }

    private void isNullAndTurnInteager(ClubRecordDTO clubRecordDTO) {
        if (StringUtils.isNotEmpty(clubRecordDTO.getAccountIds())) {
            List<Integer> accountIdList = new ArrayList<>();
            List<String> accountIds = Arrays.asList(clubRecordDTO.getAccountIds().split(","));
            //转化为Integer
            for (String accountId : accountIds) {
                if (accountId != null) {
                    accountIdList.add(Integer.valueOf(accountId));
                }
            }
            clubRecordDTO.setAccountIdsList(accountIdList);
        }
    }


}
